package com.tencent.wxpay.imagefacesign;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.tencent.wxpay.imagefacesign.sdk.WXPayUtil;
import com.tencent.wxpay.imagefacesign.sdk.WXPayXmlUtil;
import com.tencent.wxpay.imagefacesign.utils.FileUtils;
import com.tencent.wxpayface.IWxPayfaceCallback;
import com.tencent.wxpayface.WxPayFace;

import org.json.JSONObject;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by shiyanqi on 18/10/23.
 */

public class IndexActivity extends Activity{

	private RelativeLayout container;

	private TextView contentTV;
	private TextView timeTV;
	private TextView welcomeTV;
	private String nickname;
	private LinearLayout countDownContainer;
	private TextView countDownTV;
	private TextView regainTV;
	private TextView nickNameTV;
	private int leftTime;
	private String currentMeals = "早餐时段";
	private String currentTimeInterval = "6:30am-10:30am";
	private Calendar currentTimeCalendar = null;
	private boolean needSetCurrentMeals = true;
	private class AuthInfo {
		public String authinfo;
		public long expire_time = 0;
	}

	public static final String TAG = "IndexActivity";
	private AuthInfo authinfo;
	OkHttpClient okHttpClient = new OkHttpClient();
	RequestBody requestBody = null;
	Request request = null;
	private MediaPlayer mediaPlayer;

	private Integer errorType;
	private static final Integer NETERROR = 1;
	private static final Integer RECOGNITIONERROR = 2;
	private static final Integer NOVOUCHERERROR = 3;
	private static final Integer UNKNOWERROR = 4;
	private static final Integer SUCCESS = 0;

	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		initView();
		initData();
	}

	@Override
	protected void onResume() {
		super.onResume();
		initCalcTime();
//			initData();
//		new Handler().postDelayed(new Runnable() {
//			public void run() {
//				contentTV.setText("现在是早餐时段");
//				timeTV.setText("7:00am~10:30am");
//				getfaceUserInfo();
//			}
//		}, 3000);
//		initMealsTime();
	}

	private void initMealsTime() {
		//初始化时显示当前用餐时段
		currentTimeCalendar = Calendar.getInstance();
		int currHour = currentTimeCalendar.get(Calendar.HOUR_OF_DAY);//时
		int currMinute = currentTimeCalendar.get(Calendar.MINUTE);//分

		if(currHour < 11 || currHour >= 22){
			contentTV.setText("早餐时段");
			timeTV.setText("6:30am-10:30am");
		}else {
			if(currHour >= 11 && (currHour <= 14 && currMinute <= 30)){
				contentTV.setText("午餐时段");
				timeTV.setText("11:30am-14:00am");
			}else {
				contentTV.setText("晚餐时段");
				timeTV.setText("17:30am-21:30am");
			}
		}
	}

	private void initCalcTime() {
		new Thread(calcTimeRunnable).start();
	}

	private void initData() {
		authinfo = new AuthInfo();

	}

	private void initView() {
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		setContentView(R.layout.activity_index);
		welcomeTV = findViewById(R.id.tv_welcome);
		container = findViewById(R.id.container);
		contentTV = findViewById(R.id.tv_content);
		timeTV = findViewById(R.id.tv_time);
		nickNameTV = findViewById(R.id.tv_nick_name);
		countDownContainer = findViewById(R.id.count_down_container);
		countDownTV = findViewById(R.id.count_down_tv);
		regainTV = findViewById(R.id.regain_tv);
		container.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				Log.e("-------", "init");
				WxPayFace.getInstance().initWxpayface(IndexActivity.this, new IWxPayfaceCallback() {
					@Override
					public void response(Map info) throws RemoteException {
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								getRawData();
							}
						});
					}
				});
			}
		});
		regainTV.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				leftTime = 0;
			}
		});
	}


	@Override
	protected void onDestroy() {
		super.onDestroy();
		WxPayFace.getInstance().releaseWxpayface(IndexActivity.this);
		mHandler.removeCallbacks(runnable);
		calcTimeHandler.removeCallbacks(calcTimeRunnable);
	}

	private void getRawData() {
		WxPayFace.getInstance().getWxpayfaceRawdata(new IWxPayfaceCallback() {
			@Override
			public void response(Map info) throws RemoteException {
				Log.d("res|getWxpayfaceRawdata", String.valueOf(info.get("rawdata")));
				final String rawdata = info.get("rawdata").toString();
				if (rawdata == null) {
					return;
				}
				FileUtils.writeFileToSDCard(info.get("rawdata").toString());
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						getAuthInfo(rawdata);
					}
				});
			}
		});
	}


	private void getAuthInfo(String rawdata) {
		Log.d("enter | getAuthInfo ", "");
		try {

			// Create a trust manager that does not validate certificate chains
			final TrustManager[] trustAllCerts = new TrustManager[]{
					new X509TrustManager() {
						@Override
						public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
						}

						@Override
						public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
						}

						@Override
						public java.security.cert.X509Certificate[] getAcceptedIssuers() {
							return new java.security.cert.X509Certificate[]{};
						}
					}
			};

			// Install the all-trusting trust manager
			final SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
			// Create an ssl socket factory with our all-trusting manager
			final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

			OkHttpClient client = new OkHttpClient.Builder()
					.sslSocketFactory(sslSocketFactory)
					.readTimeout(5000, TimeUnit.MILLISECONDS)
					.connectTimeout(5000, TimeUnit.MILLISECONDS)
					.writeTimeout(5000, TimeUnit.SECONDS)
					.hostnameVerifier(new HostnameVerifier() {
						@Override
						public boolean verify(String hostname, SSLSession session) {
							return true;
						}
					})
					.build();
			String key = "HoojS3SHiNByJEgFrzdRAtUHiAWEo5tp";
//			String key = "renlianzhifu45879576894859307652";
			HashMap<String, String> hashMap = new HashMap<>();
//			hashMap.put("appid", "wx2b029c08a6232582");
			hashMap.put("appid", "wx0b64cb3c94d2995b");
//			hashMap.put("mch_id", "1900007041");
			hashMap.put("mch_id", "1516592331");
			hashMap.put("now", new Date().getTime() / 1000 + "");
			hashMap.put("version", "1");
			hashMap.put("sign_type", "MD5");
			hashMap.put("nonce_str", "V37ZHZVf2OrwsUV7kXTjTguP74c0byvE");
			hashMap.put("store_id", "IMG001");
			hashMap.put("store_name", "爱马哥南山店");
			hashMap.put("device_id", "DEV001");
			hashMap.put("rawdata", rawdata);
			String sign = WXPayUtil.generateSignature(hashMap, key);
			hashMap.put("sign", sign);
			String data = WXPayXmlUtil.map2Xmlstring(hashMap);

			MediaType mediaType = MediaType.parse("text/xml; charset=utf-8");
			RequestBody body = RequestBody.create(mediaType, data);

			Request request = new Request.Builder()
					.addHeader("Content-Type", "text/xml")
					.url("https://payapp.weixin.qq.com/face/get_wxpayface_authinfo")
					.post(body)
					.build();


			client.newCall(request)
					.enqueue(new Callback() {
						@Override
						public void onFailure(Call call, IOException e) {
							Log.e("onFailure|getAuthInfo ", e.toString());
							WxPayFace.getInstance().releaseWxpayface(IndexActivity.this);
							restart();
						}

						@Override
						public void onResponse(Call call, Response response) throws IOException {
							Log.d(response.protocol() + " " + response.code(), response.message());
							Headers headers = response.headers();
							for (int i = 0; i < headers.size(); i++) {
								Log.d(headers.name(i), headers.value(i));
							}
							String respStr = response.body().string();
							Log.d("onResponse: ", respStr);


							//String responseXMLString=response.body().string();
							try {
								HashMap<String, String> resp = (HashMap<String, String>) WXPayXmlUtil.xmlString2Map(respStr);
								authinfo.authinfo = resp.get("authinfo");
								if (authinfo.authinfo != null) {
									container.setClickable(false);
									getfaceUserInfo();
									Log.d("authinfo请求已发", "");
								} else {
									Log.e("authinfo为空", "");
									return;
								}
//                                authinfo.authinfo = ReturnXMLParser.parseGetAuthInfoXML(response.body().byteStream());
							} catch (Exception e) {
								e.printStackTrace();
								WxPayFace.getInstance().releaseWxpayface(IndexActivity.this);
								restart();
							}
							Log.d("onResponse|getAuthInfo", authinfo.authinfo);
						}
					});

		} catch (Exception e) {
			e.printStackTrace();
			WxPayFace.getInstance().releaseWxpayface(IndexActivity.this);
			restart();
		}
	}

	private void getfaceUserInfo() {
		Map<String, String> map = new HashMap<>();
//		map.put("appid", "wx2b029c08a6232582");
		map.put("appid", "wx0b64cb3c94d2995b");
//		map.put("mch_id", "1900007041");
		map.put("mch_id", "1516592331");
		map.put("store_id", "");
		map.put("face_authtype", "FACEID-ONCE");
		map.put("authinfo", authinfo.authinfo);
		map.put("auth_mode", "0");

		WxPayFace.getInstance().getWxpayfaceUserInfo(map, new IWxPayfaceCallback() {
			@Override
			public void response(final Map map) throws RemoteException {
				Log.e("--------map", map.toString());

				//stop
				HashMap<String, String> resp = new HashMap<>();
				resp.put("authinfo", authinfo.authinfo);
				WxPayFace.getInstance().stopWxpayface(resp, new IWxPayfaceCallback() {
					@Override
					public void response(Map map) throws RemoteException {
						Log.e(TAG, map.toString());
					}
				});

				if (map.get("return_code").equals("USER_CANCEL")) {
//					container.setClickable(true);
					WxPayFace.getInstance().releaseWxpayface(IndexActivity.this);
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							restart();
						}
					});
					return;
				}


				if (map.get("return_code").equals("SUCCESS") && !TextUtils.isEmpty((String) map.get("openid"))) {
					nickname = (String) map.get("nickname");
					String openId = (String) map.get("openid");
					if (openId != null && !TextUtils.isEmpty(openId)) {
//						verifyLegality("oWZs95X5rV9rbWnyLgCvYomMeDsA");
						verifyLegality(openId);
					}
				} else {
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							errorType = RECOGNITIONERROR;
							regainFaceInfo();
						}
					});
				}
			}
		});

	}

	private void restart(){
		new Handler().postDelayed(new Runnable() {
			public void run() {
				nickNameTV.setVisibility(View.INVISIBLE);
				welcomeTV.setText("欢迎光临");
				contentTV.setText(currentMeals);
				timeTV.setText(currentTimeInterval);
				WxPayFace.getInstance().initWxpayface(IndexActivity.this, new IWxPayfaceCallback() {
					@Override
					public void response(Map info) throws RemoteException {
						runOnUiThread(new Runnable() {
							@Override
							public void run() {
								getRawData();
							}
						});
					}
				});
			}
		}, 5000);
	}


	private void verifyLegality(String openId) {
		try {
			String time_stamp = new Date().getTime() / 1000 + "";
			Map<String, String> hashMap = new HashMap<>();
			hashMap.put("openid", openId);
			hashMap.put("device_id", "DEV001");
			hashMap.put("timestamp", time_stamp);
			hashMap.put("module", "weixin");
//			String sign = WXPayUtil.generateSignature2(hashMap, "9yIz4zptt4yl43pw_IPLQZXZwR74h3Q");
			String sign = WXPayUtil.generateSignature2(hashMap, "tMYzzvEiJUVvu-61UvxNHyG4SgGLH70");
			Log.e("-----", sign);

//			requestBody = new FormBody.Builder()
//					.add("open_id", openId)
//					.add("device_id", "DEV001")
//					.add("timestamp", time_stamp)
//					.add("_sign", sign)
//					.build();

			Map<String, Object> postMap = new HashMap<>();
			postMap.put("openid", openId);
			postMap.put("device_id", "DEV001");
			postMap.put("timestamp", time_stamp);
			postMap.put("_sign", sign);
			JSONObject jsonObject = new JSONObject(postMap);
			Log.e("------jsonObject", jsonObject.toString());
			MediaType JSON = MediaType.parse("application/json; charset=utf-8");
			RequestBody body = RequestBody.create(JSON, jsonObject.toString());

			request = new Request.Builder()
//					.url("http://demo.api.jmart.jperation.cn/a450089706/consume/face-consume")
					.url("http://api.jmart.jperation.cn/a533781337/consume/face-consume")
					.post(body)
					.build();

			okHttpClient.newCall(request).enqueue(new Callback() {
				@Override
				public void onFailure(Call call, IOException e) {
					Log.d(TAG, "onFailure: " + e.getMessage());
					errorType = NETERROR;
					regainFaceInfo();
				}

				@Override
				public void onResponse(Call call, Response response) throws IOException {
					String result = response.body().string();
					Log.e("-------result", result);
					try {
						if (result == null) {
							errorType = UNKNOWERROR;
							regainFaceInfo();
							return;
						}
						final JSONObject jsonObject = new JSONObject(result);
						final String display_msg = jsonObject.getString("display_msg");
						Boolean open = jsonObject.getBoolean("open");
						String device_id = jsonObject.getString("device_id");
//						String returnSign = jsonObject.getString("_sign");
						Map<String, String> returnMap = new HashMap<>();
						returnMap.put("device_id", device_id);
						returnMap.put("display_msg", display_msg);
						returnMap.put("open", open ? String.valueOf(1) : String.valueOf(0));
						returnMap.put("module", "weixin");
//						if (open && WXPayUtil.isSignatureValid2(returnMap, "9yIz4zptt4yl43pw_IPLQZXZwR74h3Q", returnSign)) {
//						if (open && WXPayUtil.isSignatureValid2(returnMap, "tMYzzvEiJUVvu-61UvxNHyG4SgGLH70", returnSign)) {
						if (open) {
							runOnUiThread(new Runnable() {
								@Override
								public void run() {
									nickNameTV.setVisibility(View.VISIBLE);
									nickNameTV.setText(nickname);
									errorType = SUCCESS;
									regainFaceInfo();
									return;
								}
							});
						} else {
							runOnUiThread(new Runnable() {
								@Override
								public void run() {
									errorType = NOVOUCHERERROR;
									regainFaceInfo();
									return;
								}
							});
						}
					} catch (Exception e) {
						e.printStackTrace();
						errorType = UNKNOWERROR;
						regainFaceInfo();
					}
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
			errorType = UNKNOWERROR;
			regainFaceInfo();
		}
	}

	private void regainFaceInfo() {
		leftTime = 10;
		new Thread(runnable).start();
	}

	Runnable runnable = new Runnable() {
		@Override
		public void run() {
			mHandler.sendEmptyMessage(3);
			leftTime--;
			if (leftTime <= 0) {
				mHandler.sendEmptyMessage(5);
			} else {
				mHandler.sendEmptyMessage(4);
				mHandler.postDelayed(this, 1000);
			}
		}
	};

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			needSetCurrentMeals = false;
			switch (msg.what) {
				case 0:
					setResult(RESULT_OK);
					break;
				case 3:
					countDownContainer.setVisibility(View.VISIBLE);
					if (errorType == NETERROR) {
//						timeTV.setText("网络错误");
						welcomeTV.setText("网络错误");
					} else if (errorType == RECOGNITIONERROR) {
//						timeTV.setText("未能识别人脸");
						welcomeTV.setText("未能识别人脸");
						contentTV.setText("请先授权人脸");
						timeTV.setText("详询服务人员");
					} else if (errorType == NOVOUCHERERROR) {
//						timeTV.setText("无可用餐券");
						welcomeTV.setText("无可用餐券");
						contentTV.setText("请先获取餐券");
						timeTV.setText("详询服务人员");
					} else if (errorType == UNKNOWERROR) {
//						timeTV.setText("未知错误");
						welcomeTV.setText("未知错误");
					} else if (errorType == SUCCESS) {
						welcomeTV.setText("请入座就餐");
//						contentTV.setText("现在是早餐时段");
//						timeTV.setText("7:00am~10:30am");
					}
					break;
				case 4:
					countDownTV.setText(leftTime + "S");
					break;
				case 5:
					needSetCurrentMeals = true;
					countDownContainer.setVisibility(View.GONE);
					nickNameTV.setVisibility(View.INVISIBLE);
					welcomeTV.setText("欢迎光临");
					contentTV.setText(currentMeals);
					timeTV.setText(currentTimeInterval);
					getfaceUserInfo();
					break;
			}

		}
	};


	Runnable calcTimeRunnable = new Runnable() {
		@Override
		public void run() {
			//计算时间修改
			currentTimeCalendar = Calendar.getInstance();
			if(currentTimeCalendar != null){
				final int currHour = currentTimeCalendar.get(Calendar.HOUR_OF_DAY);//时
				final int currMinute = currentTimeCalendar.get(Calendar.MINUTE);//分

				if(currHour < 11 || currHour >= 22){
					calcTimeHandler.sendEmptyMessage(11);
				}else {
					if(currHour >= 11 && (currHour <= 14 && currMinute <= 30)){
						calcTimeHandler.sendEmptyMessage(12);
					}else {
						calcTimeHandler.sendEmptyMessage(13);
					}
				}
				calcTimeHandler.postDelayed(this, 60000);
			}
		}
	};

	private Handler calcTimeHandler = new Handler(){
		public void handleMessage(Message msg) {
			switch (msg.what) {
				//早餐
				case 11:
					currentMeals = "早餐时段";
					currentTimeInterval = "6:30am-10:30am";
					break;
				//午餐
				case 12:
					currentMeals = "午餐时段";
					currentTimeInterval = "11:30am-14:00am";
					break;
				//晚餐
				case 13:
					currentMeals = "晚餐时段";
					currentTimeInterval = "17:30am-21:30am";
					break;
			}
			if(needSetCurrentMeals){
				contentTV.setText(currentMeals);
				timeTV.setText(currentTimeInterval);
			}
		}

	};

	/**
	 * 打开assets下的音乐mp3文件
	 */
	private void openAssetMusics(boolean success) {

		try {
			//播放 assets/a2.mp3 音乐文件
			AssetFileDescriptor fd = null;
			if(success){
				fd = getAssets().openFd("success.mp3");
			}else {
				fd = getAssets().openFd("failed.mp3");
			}
			mediaPlayer = new MediaPlayer();
			mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
			mediaPlayer.prepare();
			mediaPlayer.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


}
